﻿using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using WssEvents;
using WssNative.Vibrations;
using WssUtils;

namespace JQMergeFramework
{
    
    //塔吊控制器
    public class TowerControl: MonoBehaviour
    {
        public static TowerControl I;
        
        [Header("吊台")]
        public Transform towerPlatform;
        
        [Header("房子生成位置")]
        public Transform[] trackPoint;
        
        
        [Header("塔吊底座")]
        public GameObject towerBaseObj;
        
        [Header("放置提示特效")]
        //放置特效提示
        public ParticleSystem  placeTipsPool;
        
        private List<CityUnit> cityUnitList = new List<CityUnit>();

        //塔吊生成节点
        private List<Transform> towerNodeList = new List<Transform>();
        
        

        //是否在播放游戏开始时的城堡动画
        public bool isPlayStartCityAnim = false;

        
        [Header("塔吊距离棋盘的Y差距")] public float towerCityYDistance = 11F;
        
        //塔吊节点高度
        private float towerFrameNodeHeight;
        
        //传送带高度
        public Vector3 trackSize;
        
        //塔吊台子的高度
        private float towerBaseHeight;
        
        
        private void Awake()
        {
            I = this;

            MergeManager manager = MergeManager.Instance;
            
            trackSize = manager.scriptablePrefab.track.transform.GetChild(0).GetComponent<MeshRenderer>().bounds.size;
            
            towerFrameNodeHeight = manager.scriptablePrefab.towerFrame.transform.GetChild(0).GetComponent<MeshRenderer>().bounds.size.y;
            
            towerBaseHeight = towerBaseObj.transform.GetChild(0).GetComponent<MeshRenderer>().bounds.size.y;
        }


        // private void Start()
        // {
        //     InitCity();
        // }

        
        private void OnDisable()
        {
            GlobalEvent.Removelistener(GameEvents.OnCreateCity,CreateCity);
        }

        private void OnEnable()
        {
            GlobalEvent.Addlistener(GameEvents.OnCreateCity,CreateCity);
        }


        private List<TrackUnit> trackList = new List<TrackUnit>();
        
        /// <summary>
        /// 生成3个建筑
        /// </summary>
        /// <param name="assignLvList">指定建筑等级</param>
        public void InitCity(List<int> assignLvList = null)
        {
            isPlayStartCityAnim = true;
            MergeManager manager = MergeManager.Instance;
            
            for (int i = 0; i < trackList.Count; i++)
            {
                trackList[i].PutTrack();
            }
            trackList.Clear();
            
            for (int i = 0; i < 4; i++)
            {
                Transform track = EffectPool.I.GetPoolObject(PoolName.TrackTemplate).transform;
                track.SetParent(towerPlatform);
                trackList.Add(track.GetComponent<TrackUnit>());
            }

            int trackPointCount = trackPoint.Length;
            int trackListCount = trackList.Count;
            Vector3 tractStartPos = trackPoint[trackPointCount - 1].position;
            
            Sequence sq = DOTween.Sequence();
            //创建3个房子
            for (int i = 0; i < 3; i++)
            {
                MyRandom.ResetSeed();

                CityData cityData = CityConfig.RandomCityLv();
                
                if (assignLvList !=null && i < assignLvList.Count)
                {
                    cityData.level = assignLvList[i];
                }
                
                //根据等级加载对应的建筑
                CityUnit cityUnit = LoadCityObj(cityData.level);
                    
                TrackUnit track = trackList[i];
                track.SetParent(this.towerPlatform,trackPoint[trackPointCount-1].position - new Vector3(trackSize.x * (4-i),0,0));
                track.SetIndex(i);
                
                cityUnit.BindCityTrack(track);
                cityUnit.transform.localPosition = Vector3.zero + new Vector3(0,trackSize.y,0);
                
                cityUnitList.Add(cityUnit);
                
                sq.Join(track.transform.DOMoveX(trackPoint[i].position.x, GameCfg.DownTime*2).SetEase(Ease.Linear));
            }
            
            TrackUnit trackEnd =  trackList[trackListCount-1];
            trackEnd.SetParent(this.towerPlatform,tractStartPos - new Vector3(trackSize.x,0,0));
            sq.Join(trackEnd.transform.DOMoveX(tractStartPos.x, GameCfg.DownTime*2).SetEase(Ease.Linear));

            sq.OnComplete(() =>
            {
                //打开UI
                UIGame uiGame = UIManager.Instance.GetWindow<UIGame>(true);
                uiGame.OnRefreshGameTipsUi();
                uiGame.RefreshBuildMainCityNum(false);
                UIManager.Instance.GetWindow<UICityLvTips>(true);
                ShowPlaceTipsEft(true);
                
                isPlayStartCityAnim = false;
                InputManager.I.isNoRayClick = false;
            });
            
            sq.Play();
        }


        //展示放置特效
       public void ShowPlaceTipsEft(bool isShow)
        {
            placeTipsPool.transform.position = trackPoint[0].position + Vector3.up;
            placeTipsPool.gameObject.SetActive(isShow);
        }

       //清除履带记录
       public void RemoveTrackRecord(TrackUnit track)
       {
           trackList.Remove(track);
       }

       /// <summary>
        /// 放置房子时再次生成一个
        /// </summary>
        void CreateCity()
        {
            ShowPlaceTipsEft(false);
            //生成房子
            CityData cityData = CityConfig.RandomCityLv();
            
        
            int trackPointCount = trackPoint.Length;
            
            //尾部传送带前移
            TrackUnit trackEnd = trackList[trackList.Count-1];
            trackEnd.SetParent(this.towerPlatform);

            TrackUnit newTrack = EffectPool.I.GetPoolObject(PoolName.TrackTemplate).GetComponent<TrackUnit>();
            Vector3 tractStartPos = trackPoint[trackPointCount - 1].position;
            newTrack.SetParent(this.towerPlatform,tractStartPos - new Vector3(trackSize.x,0,0));
            trackList.Add(newTrack);
            
             //生成城堡
            CityUnit cityUnit = LoadCityObj(cityData.level);
            cityUnit.BindCityTrack(trackEnd);
            //设置高度，做下落动画
            cityUnit.transform.localPosition = Vector3.zero + new Vector3(0,10,0);
            cityUnitList.Add(cityUnit);
            
            isPlayStartCityAnim = true;
            // DOTween.Kill(this.GetInstanceID());
            //动画处理
            DOTween.Sequence()
                .Append(cityUnit.transform.DOLocalMoveY(trackSize.y,GameCfg.DownTime).SetEase(Ease.Linear))
                .Append(trackList[0].transform.DOMoveX(trackPoint[0].position.x, GameCfg.DownTime).SetEase(Ease.Linear))
                .Join(trackList[1].transform.DOMoveX(trackPoint[1].position.x, GameCfg.DownTime).SetEase(Ease.Linear))
                .Join(trackList[2].transform.DOMoveX(trackPoint[2].position.x, GameCfg.DownTime).SetEase(Ease.Linear))
                .Join(trackList[3].transform.DOMoveX(trackPoint[3].position.x, GameCfg.DownTime).SetEase(Ease.Linear))
                
                .OnComplete(() =>
                {
                    AudioManager.Instance.Play(AudioName.CreateCity);
                    isPlayStartCityAnim = false;
                    ShowPlaceTipsEft(true);
                    
                    //更新绑定的塔吊索引
                    for (int i = 0; i < trackList.Count; i++)
                    {
                        trackList[i].SetIndex(i);
                    }
                }).Play().SetId(this.GetInstanceID());
        }

        
        
        /// <summary>
        /// 开始游戏时放置3个建筑
        /// </summary>
        public  async UniTask InitPlaceThreeCity()
        {
            InputManager.I.isNoRayClick = true;
            GroundBase[,] groundArray = MergeManager.Instance.groundArray;
            List<Vector2Int> vector2List = CommonFun.GetVector2List(groundArray);
            
            //创建3个房子
            for (int i = 0; i < vector2List.Count; i++)
            {
                int rRow =  vector2List[i].x;
                int rCol = vector2List[i].y;
                
                CityData cityData = CityConfig.RandomCityLv();
                
                CityUnit cityUnit =  LoadCityObj(cityData.level);
                cityUnit.SetInitTowCity();
                
                groundArray[rRow,rCol].ChangeBindCity(cityUnit);
                await UniTask.Delay(TimeSpan.FromSeconds(GameCfg.DownTime));
            }
            
            InitCity();
        }



        //替换塔吊第一个房子，改用指定的房子替代
        public void ReplaceTowerOneCity(CityUnit city)
        {
            cityUnitList.Insert(0,city);
        }


        public CityUnit LoadCityObj(int lv)
        {
            Mesh mesh = MergeManager.Instance.scriptablePrefab.GetLitCity(0, lv);
            CityUnit unit = CityPool.I.Get(); 
            
            UnitDataBase data = new UnitDataBase();
            data.UnitLevel = lv;
            unit.Init(mesh,data);
            
            return unit;
        }
        
        public CityUnit DequeueUnitDataBase()
        {
            CityUnit city = cityUnitList[0];

            cityUnitList.RemoveAt(0);
            return city;
        }

        
        /// <summary>
        /// 重置建筑栏的建筑
        /// </summary>
        /// <param name="mayMergeLvList">可以放置的建筑等级</param>
        public void ResetCityUnitQueue(List<int> mayMergeLvList)
        {
            ShowPlaceTipsEft(false);
            
            TowerControl.I.isPlayStartCityAnim = true;
            
            int count = cityUnitList.Count;
            for (int i = 0; i < count; i++)
            {
                CityUnit city =  cityUnitList[i];
                city.transform.DOKill();
                city.DestroyTrack();
                city.RDestroy();
            }
            cityUnitList.Clear();
            
            InitCity(mayMergeLvList);
        }
        
        



        //合成新的房子动画表现
        public void PlayNewCityTips(CityUnit city, Action callback = null)
        {
            //记录历史最高等级
            if (!DataManager.Instance.SetMergeRecordDict(city.UnitData))
            {
                callback?.Invoke();
                return;
            }
            
            //禁用点击
            InputManager.I.isNoRayClick = true;
            
            
            UIManager.Instance.GetWindow<UnLockNewCity>().Open(city.Level,() =>
            {
                InputManager.I.isNoRayClick = false;
                callback?.Invoke();
            });
        }

        
        //通关动画处理
        public void StartPassAnim(List<int> newBuildIdList)
        {
            int tempLv = DataManager.Instance.Lv;
            
            InputManager.I.isNoRayClick = true;
            
            //隐藏UI
            UIManager.Instance.GetWindow<UIGame>(false);
            UIManager.Instance.GetWindow<UICityLvTips>(false);
            UIManager.Instance.GetWindow<UIAddLvTips>().Open(BuildTipsType.ScoreFinish);
            
            Sequence sq = DOTween.Sequence();
            sq.AppendInterval(1F);
            sq.AppendCallback(() =>
            {
                // VibrationController.Instance.ImpactSustain(0.2F,2F);
                //相机震动\正视前方
                GameCameraControl.I.CameraMoveFront();
            });
            sq.AppendInterval(2.5F);
            sq.AppendCallback(() =>
            {
                CityBaseControl.I.SetShowChessboard(false);
                //清空棋盘
                // MergeManager.Instance.ClearCity();
                //清空塔吊的房子
                // ClearTowerCity();
                
                // VibrationController.Instance.ImpactSustain(0.2F,3F);
                
                //播放盖楼动画
                MainCityControl.I.PlayBuildTheHouse(newBuildIdList);
            });
            sq.AppendInterval(newBuildIdList.Count);
            sq.AppendCallback(() =>
            {
                CityBaseControl.I.ChessboardMove();
                //播放相机回正动画
                GameCameraControl.I.CameraMoveLockAtChessboard();
                //塔吊升高
                StartUpTowerAnim();
            });
            sq.AppendInterval(1F);
            sq.AppendCallback(() =>
            {
                //打开UI
                UIGame uiGame = UIManager.Instance.GetWindow<UIGame>();
                uiGame.OnRefreshGameTipsUi();
                uiGame.RefreshBuildMainCityNum();
                
                UIManager.Instance.GetWindow<UICityLvTips>(true);
          
                
                ShowPlaceTipsEft(true);
            
                //执行弹窗
                CoroutineQueue.Instance.DoCommand();
                
                InputManager.I.isNoRayClick = false;
            });
            
            sq.Play();
        }


        //清空塔吊的建筑
        public void ClearTowerCity()
        {
            int count = cityUnitList.Count;
            for (int i = 0; i < count; i++)
            {
                CityUnit city =  cityUnitList[i];
                city.transform.DOKill();
                city.DestroyTrack();
                city.RDestroy();
            }

            for (int i = 0; i < trackList.Count; i++)
            {
                trackList[i].PutTrackAnim();
            }
            
            cityUnitList.Clear();
        }


        //升高塔吊
        void StartUpTowerAnim()
        {
            //塔吊上升高度
            float towerHeight = MainCityControl.I.GetCityNodeHeight(false) - towerCityYDistance;
            
            int cCount = (int) Math.Ceiling((towerHeight - towerBaseHeight) / towerFrameNodeHeight);
            
            int nodeCount = towerNodeList.Count;

            Sequence sq = DOTween.Sequence();


            if (cCount == towerNodeList.Count)
            {
                sq.Append(towerPlatform.DOMoveY(towerHeight, 1f));
            }
            else
            {
                for (int i = 0; i < cCount; i++)
                {
                    if (i >= nodeCount)
                    {
                        
                        GameObject cObj =  Instantiate(MergeManager.Instance.scriptablePrefab.towerFrame, this.transform);
                        towerNodeList.Add(cObj.transform); 
                        cObj.transform.localPosition = Vector3.zero;
                        float targetY = towerBaseHeight + (i * towerFrameNodeHeight);
                        
                        sq.Append(cObj.transform.DOMoveY(targetY, 0.5F));

                        if ((targetY + towerFrameNodeHeight) > towerHeight)
                        {
                            sq.Append(towerPlatform.DOMoveY(towerHeight, 0.5f));
                        }
                        else
                        {
                            sq.Append(towerPlatform.DOMoveY(targetY, 0.5f));
                        }
                    }
                }
            }
            
            sq.Play();
        }


        //初始化塔吊
       public void InitTower()
       {
           //塔吊上升高度
            float towerHeight = MainCityControl.I.GetCityNodeHeight(false) - towerCityYDistance;
            
            int cCount = (int) Math.Ceiling((towerHeight - towerBaseHeight) / towerFrameNodeHeight);
            
            int nodeCount = towerNodeList.Count;

            Sequence sq = DOTween.Sequence();
            
            if (cCount == towerNodeList.Count)
            {
                towerPlatform.position = new Vector3(towerPlatform.position.x, towerHeight, towerPlatform.position.z);
            }
            else
            {
                for (int i = 0; i < cCount; i++)
                {
                    if (i >= nodeCount)
                    {
                        float targetY = towerBaseHeight + (i * towerFrameNodeHeight);
                        
                        GameObject cObj =  Instantiate(MergeManager.Instance.scriptablePrefab.towerFrame, this.transform);
                        towerNodeList.Add(cObj.transform); 
                        
                        cObj.transform.localPosition = new Vector3(0,targetY,0);
                        
                        if ((targetY + towerFrameNodeHeight) > towerHeight)
                        {
                            
                            towerPlatform.position = new Vector3(towerPlatform.position.x, towerHeight, towerPlatform.position.z);
                        }
                        else
                        {
                            towerPlatform.position = new Vector3(towerPlatform.position.x, targetY, towerPlatform.position.z);
                        }
                    }
                }
            }
        }


       public void SetShow(bool isShow)
       {
           this.gameObject.SetActive(isShow);
       }
    }
}